﻿using DevExpress.Xpf.Core;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Navigation;
using TeBigScreenWpf.Pages;
using TeBigScreenWpf.ViewModels;
using Timer = System.Timers.Timer;

namespace TeBigScreenWpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int VisualCount { get; set; } = 0;

        ContextMenu MyContextMenu => this.FindResource("cmWindow") as ContextMenu;

        private Frame FrameLeft = new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden };
        private Frame FrameMain = new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden };
        private Frame FrameRight = new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden };

        private Dictionary<Frame, Page> Current = new Dictionary<Frame, Page>();

        private Timer mTimer = new Timer();

        private bool mAutoLeft = false;
        private bool mAutoMain = false;
        private bool mAutoRight = false;

        public static Dictionary<string, Page> pageNewList = new Dictionary<string, Page>()
        {
            {"主屏中", new Page4()  },
            {"主屏右", new Page11()  },
            {"主屏左3D", new Page16()  },
            {"工作量统计", new Page6()  },
            {"警情布局1",  new Page2()  },
            {"警情布局2",  new Page8()  },
            {"警情布局3",  new Page3()  },
            {"地图布局1",  new Page5()  },
            {"地图布局2",  new Page7()  },
            {"分析布局1",  new Page13()  },
            {"分析布局2",  new Page15()  },
        };

        public MainWindow() : this(true, true, true)
        {
            //NavigatePage(FrameMain, pageList.Last());
        }

        public MainWindow(bool left, bool main, bool right)
        {
            InitializeComponent();

            MyContextMenu.ContextMenuOpening += MyContextMenu_ContextMenuOpening;

            this.PreviewMouseRightButtonUp += MainWindow_PreviewMouseRightButtonUp;
            this.Loaded += MainWindow_Loaded;

            DataContext = vmGlobal.vmMainWindow.Value;

            NavigatePage(FrameLeft, pageNewList.Values.OfType<Page16>().First());
            NavigatePage(FrameMain, pageNewList.Values.OfType<Page4>().First());
            NavigatePage(FrameRight, pageNewList.Values.OfType<Page11>().First());

            SetViews(left, main, right);

            mTimer.Interval = 5000;
            mTimer.Elapsed += MTimer_Elapsed;
            mTimer.Start();
        }

        public void ShowFullScreen()
        {
            Show();
            this.SetFullScreen(VisualCount);
        }

        private void MyContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs arg)
        {
            if (LogicalTreeHelper.FindLogicalNode(MyContextMenu, "miNew") is MenuItem menu)
            {
                menu.Items.Clear();

                foreach (var kv in HotKeyWindow.pageNewList)
                {
                    var page = kv.Value;

                    var item = new MenuItem()
                    {
                        Header = $"打开页面 - {kv.Key}",
                    };

                    item.Click += (o, e) => new QuickWindow(page, kv.Key).Show();

                    menu.Items.Add(item);
                }
            }
        }

        private void MTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Dispatcher.InvokeAsync(() =>
            {
                if (mAutoLeft)
                    SetNextPage(FrameLeft);

                if (mAutoMain)
                    SetNextPage(FrameMain);

                if (mAutoRight)
                    SetNextPage(FrameRight);
            });
        }

        private Frame GetFrame()
        {
            ContextMenu cm = this.FindResource("cmWindow") as ContextMenu;

            if (cm.IsVisible)
            {
                var pt = (Point)cm.Tag;

                pt = this.TranslatePoint(pt, grid_main);

                if (FrameMain.IsVisible && FrameMain.GetVisualBounds().Contains(pt))
                    return FrameMain;

                if (FrameLeft.IsVisible && FrameLeft.GetVisualBounds().Contains(pt))
                    return FrameLeft;

                if (FrameRight.IsVisible && FrameRight.GetVisualBounds().Contains(pt))
                    return FrameRight;

                return null;
            }
            else
            {
                return FrameMain;
            }
        }

        private void SetSplitScreen()
        {
            for (int i = 0; i < 3; i++)
            {
                var item = HotKeyWindow.pageNewList.ElementAt(i);
                new QuickWindow(item.Value, item.Key, i).Show();
            }

            this.WindowState = WindowState.Minimized;
        }

        private Page NextPage(Page current = null)
        {
            var pageList = pageNewList.Values;

            var page = pageList.SkipWhile(r => r != current).Skip(1).FirstOrDefault();

            page = page ?? pageList.First();

            if (Current.Values.Contains(page))
                page = NextPage(page);

            return page;
        }

        private Page PrevPage(Page current = null)
        {
            var pageList = pageNewList.Values;

            var page = pageList.AsEnumerable().Reverse().SkipWhile(r => r != current).Skip(1).FirstOrDefault();

            page = page ?? pageList.Last();

            if (Current.Values.Contains(page))
                page = PrevPage(page);

            return page;
        }

        private void SetCheckViews()
        {
            SetViews(
                GetMenuChecked("miScreenLeft"),
                GetMenuChecked("miScreenMiddle"),
                GetMenuChecked("miScreenRight")
            );
        }

        private void SetEmptyViews(int count)
        {
            content_holder.Children.Clear();
            VisualCount = count;

            this.SetCrossMonitor(VisualCount);

            grid_main.Width = 2048 * VisualCount;
        }

        private void SetMenuChecked(string menu, bool bcheck)
        {
            if (LogicalTreeHelper.FindLogicalNode(MyContextMenu, menu) is MenuItem item)
            {
                item.IsChecked = true;
            }
        }

        private bool GetMenuChecked(string menu)
        {
            if (LogicalTreeHelper.FindLogicalNode(MyContextMenu, menu) is MenuItem item)
            {
                return item.IsChecked;
            }

            return false;
        }

        private void SetViews(bool left, bool main, bool right)
        {
            content_holder.Children.Clear();
            VisualCount = 0;

            if (left)
            {
                SetMenuChecked("miScreenLeft", true);

                content_holder.Children.Add(FrameLeft);

                ++VisualCount;
            }

            if (main)
            {
                SetMenuChecked("miScreenMiddle", true);

                content_holder.Children.Add(FrameMain);

                ++VisualCount;
            }

            if (right)
            {
                SetMenuChecked("miScreenRight", true);

                content_holder.Children.Add(FrameRight);

                ++VisualCount;
            }

            this.SetCrossMonitor(VisualCount);

            grid_main.Width = 2048 * VisualCount;
        }

        private void NavigatePage(Frame f, Page p)
        {
            Current[f] = p;
            f.Navigate(p);
        }

        private void SetNextPage(Frame frm = null)
        {
            var f = frm ?? GetFrame();

            if (f != null)
            {
                Page c = null;
                Current.TryGetValue(f, out c);

                NavigatePage(f, NextPage(c));
            }
        }

        private void SetPrevPage(Frame frm = null)
        {
            var f = frm ?? GetFrame();

            if (f != null)
            {
                Page c = null;
                Current.TryGetValue(f, out c);

                NavigatePage(f, PrevPage(c));
            }
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.SetCrossMonitor(VisualCount);
        }

        private void MainWindow_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            ContextMenu cm = MyContextMenu;
            cm.PlacementTarget = sender as UIElement;
            cm.Tag = Mouse.GetPosition(this);
            cm.IsOpen = true;
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.InvokeAsync(() =>
            {
                if (e.Source is MenuItem mi)
                {
                    switch (mi.Name)
                    {
                        case "miFullscreen":
                            this.SetFullScreen(VisualCount);
                            break;

                        case "miRestore":
                            this.ResetFullScreen(VisualCount);

                            break;

                        case "miClose":
                            this.Close();
                            break;

                        case "miOption":
                            new OptionWindow().Show();
                            break;

                        case "miAutoPageLeft":
                            mAutoLeft = !mAutoLeft;
                            break;

                        case "miAutoPageMiddle":
                            mAutoMain = !mAutoMain;
                            break;

                        case "miAutoPageRight":
                            mAutoRight = !mAutoRight;
                            break;

                        case "miPrevious":
                            SetPrevPage();
                            break;

                        case "miNext":
                            SetNextPage();
                            break;

                        case "miScreenEmpty1":
                            SetEmptyViews(1);
                            break;

                        case "miScreenEmpty2":
                            SetEmptyViews(2);
                            break;

                        case "miScreenEmpty3":
                            SetEmptyViews(3);
                            break;

                        case "miTitle":
                            ui_title.Visibility = ui_title.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
                            break;

                        case "miScreen3":
                            SetSplitScreen();
                            break;

                        case "miScreenLeft":
                        case "miScreenMiddle":
                        case "miScreenRight":
                            SetCheckViews();
                            break;

                        default:
                            break;
                    }
                }
            });
        }
    }
}